/**
 * 
 */
package com.google.gwt.indexeddb.client;

import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.core.client.JavaScriptObject;

/**
 * The IDBCursor interface of the IndexedDB API represents a cursor for
 * iterating over multiple records in a database. Operations are performed on
 * the underlying index or object store. It enables an application to
 * asynchronously process all the records in the cursor's range
 * 
 * @author Chan Le <gwt /at/ chanvn.com>
 * @see <a href="http://www.w3.org/TR/IndexedDB/#cursor">W3C IndexedDB
 *      cursor</a>
 */
public class IDBCursor extends JavaScriptObject {

  protected IDBCursor() {
  }

  /**
   * This cursor includes duplicates, and its direction is monotonically
   * increasing in the order of keys.
   */
  public static final int NEXT = 1;

  /**
   * This cursor does not include duplicates, and its direction is monotonically
   * increasing in the order of keys. If multiple records exist with the same
   * key, only the first one is retrieved.
   */
  public static final int NEXT_NO_DUPLICATE = 1;

  /**
   * This cursor includes duplicates, and its direction is monotonically
   * decreasing in the order of keys.
   */
  public static final int PREV = 2;

  /**
   * This cursor does not include duplicates, and its direction is monotonically
   * decreasing in the order of keys. If multiple records exist with the same
   * key, only the first one iterated to is retrieved.
   */
  public static final int PREV_NO_DUPLICATE = 3;

  /**
   * Advances the cursor to the next position along its direction, to the item
   * whose key matches the optional key parameter. If no key is specified,
   * advance to the immediate next position, based on the cursor's direction.
   * 
   * @param key The key to which to move the cursor's position
   * @throws IDBDatabaseException
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBCursor-continue">W3C
   *      IDBCursor-continue</a>
   */
  public final void cursorContinue(Object key) throws IDBDatabaseException {
    try {
      cursorContinue0(key);
    } catch (JavaScriptException e) {
      throw new IDBDatabaseException(e.getName(), e);
    }
  }

  private final native void cursorContinue0(Object key) /*-{
		  this['continue'](key);
  }-*/;

  /**
   * Returns an IDBRequest object, and, in a separate thread, deletes the record
   * at the cursor's position, without changing the cursor's position, setting
   * the cursor's value to null.
   * 
   * @return A request object on which subsequent events related to this
   *         operation are fired.
   * @throws IDBDatabaseException
   * @see <a href="">W3C </a>
   */
  public final IDBRequest delete() throws IDBDatabaseException {
    try {
      return delete0();
    } catch (JavaScriptException e) {
      throw new IDBDatabaseException(e.getName(), e);
    }
  }

  private final native IDBRequest delete0() /*-{
		return this['delete']();
  }-*/;

  /**
   * @return The direction of traversal of the cursor. See Constants for
   *         possible values.
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBCursor-direction">W3C
   *      IDBCursor-direction</a>
   */
  public final native int getDirection() /*-{
		return this.direction;
  }-*/;

  /**
   * @return The key for the record at the cursor's position. If the cursor is
   *         outside the range, this is undefined
   * @see <a href="http://www.w3.org/TR/IndexedDB/#widl-IDBCursor-key">W3C
   *      IDBCursor-key</a>
   */
  public final native Object getKey() /*-{
		return this.key;
  }-*/;

  /**
   * @return The value for the record at the cursor's position. If the cursor is
   *         outside the range, this is undefined. If this returns an object, it
   *         returns the same object every time, unless the cursor is iterated.
   *         Changes to that object are seen by anyone inspecting it, but do not
   *         affect the database
   * @see <a
   *      href="https://developer.mozilla.org/en/IndexedDB/IDBCursor#continue">W3C
   *      Cursor Value</a>
   */
  public final native Object getValue() /*-{
		return this.value;
  }-*/;

  /**
   * @param value The value for the record at the cursor's position. If the
   *        cursor is outside the range, this is undefined. If this returns an
   *        object, it returns the same object every time, unless the cursor is
   *        iterated. Changes to that object are seen by anyone inspecting it,
   *        but do not affect the database
   * @see <a
   *      href="https://developer.mozilla.org/en/IndexedDB/IDBCursor#continue">W3C
   *      Cursor Value</a>
   */
  public final native void setValue(Object value)/*-{
		this.value = value;
  }-*/;

  /**
   * Returns an IDBRequest object, and, in a separate thread, stores a
   * structured clone of the value parameter into the underlying object store,
   * at the cursor's current position.
   * 
   * @param value The value to be stored
   * @return A request object on which subsequent events related to this
   *         operation are fired.
   * @throws IDBDatabaseException
   * @see <a href="">W3C </a>
   */
  public final IDBRequest update(Object value) throws IDBDatabaseException {
    try {
      return update0(value);
    } catch (JavaScriptException e) {
      throw new IDBDatabaseException(e.getName(), e);
    }
  }

  private final native IDBRequest update0(Object value) /*-{
		return this.update(value);
  }-*/;

}
